% ----------------------------------------------------------------------- %
% CAPITULO 4
% ----------------------------------------------------------------------- %

\chapter{Cenários}
\label{Cenarios}

\section{Cenários estudados}

Após os estudos bibliográficos sobre o NSIS e com base nos documentos lidos,
foram definidos alguns cenários de testes com fins de aprofundar o estudo dos
mecanismos integrantes do referido protocolo, bem como os seus modos de
operação.

Os seguintes cenários foram definidos para este trabalho:

\begin{enumerate}
\item Cenário 1: Sinalização por fluxo individual, com mensagem de reserva a
partir do emissor do fluxo;
\item Cenário 2: Sinalização por fluxo individual, com mensagem de reserva a
partir do receptor;
\item Cenário 3: Sinalização com reserva real de recursos a partir do emissor do
fluxo;
\item Cenário 4: Detalhamento do mecanismo de reserva e de gerência de
recursos;
\item Cenário 5: Atualização de reserva face a mudanças de rota e o mecanismo de
soft-state;
\end{enumerate}

\section{Aspectos da Plataforma de Testes e Operação do protocolo de Goettingen}

\subsection{Plataforma de Testes}

Para a análise do protocolo foram utilizadas máquinas virtuais linux UML. Estas
máquinas facilitam o controle das diversas entidades dos protocolos e evitam a
complexidade adicional no uso de diversas máquinas reais.

Um sistema de arquivos foi construído para o uso nas máquinas virtuais UML,
conforme descrito em \ref{Montar_vm}, onde foi instalada a versão 0.6.0 do
protocolo NSIS implementado na Universidade de Goettingen. Esta implementação
foi a escolhida face à outras, dada a aparente forma estruturada do projeto e
das constantes atualizações a que vem sendo submetida.

Dentre os componentes do NSIS implementado pela universidade de Goettingen
podemos citar o GIST (NTLP) e os protocolos de aplicação: NSIS-QOSD (Servidor
de gerenciamento de QoS) e o NAT/FW NSLP para testes e gerenciamento com
\textit{firewalls}. Além disto, um cliente do NSIS-QoS permite dar início as
sinalizações, segundo várias opções possíveis.

Em adição, nos cenários contruídos foram utilizadas ferramentas para análise e
geração de tráfego, tais como o ``tcpdump'' e o ``iperf''.

\subsection{Estrutura e Configuração do NSIS}
\label{cenario_conf}

Para o seu funcionamento, a implementação de Goettingen do NSIS requer que sua
camada de transporte (GIST) e os protocolos de sinalização (NSLPs) se executem
como processos independentes. Cada máquina, que se comporta como uma entidade
NSIS, deve executar no mínimo o protocolo GIST e um protocolo NSLP.

O processo GIST possue uma API, baseada em sockets, para acesso
as funcionalidades de transporte. Os demais protocolos NSLP acessam esta
API para o transporte de suas mensagens. Cada protocolo NSLP é implementado como
um processo. O protocolo nsis-qos, foco de estudo deste trabalho, possui também
uma interface via sockets, para permitir o acesso as suas funcionalidades por
parte de um programa cliente.

Dentro do diretório do NSIS,
encontra-se o diretório \textit{bin} com arquivos compilados do NSLP, entre eles
os arquivos nsis, nsis-qos e o nsis-ping, além do arquivo de configuração
nsis.conf.

O binário nsis é um dos principais arquivos, que funciona como um \textit{daemon} de
controle central: quando executado carrega as informações do arquivo de
configuração nsis.conf e executa os demais componentes do protocolo. No caso
deste estudo, os protocolos GIST e o protocolo nsis-qos.

No arquivo de configuração nsis.conf é possível habilitar os \textit{daemons} que se
deseja iniciar junto com a execução do nsis, além de configuração de IP, NAT/FW
e parâmetros da Função de Gerência de Recursos-RMF. Para os cenários citados, no
arquivo nsis.conf de todos as entidades iniciadas, foi habilitado o parâmetro
\textit{nslp.startQoS = yes}, que faz com que o \textit{daemon} nsis-qosd carregue
junto com o nsis.

Um importante detalhe da configuração do arquivo nsis.conf está na cofinguração
de roteamento de rede através do parâmetro \textit{readRoutingTable} que permite
ao NSIS ler a tabela de roteamento do sistema  ou carregar as
configurações do arquivo, por interface.

A configuração utilizada na montagem do cenário, bem como configuração resumida
do arquivo nsis.conf de cada ponto está listada no respectivo ambiente de teste.
Os detalhes destes arquivos pode ser vistos no anexo \ref{cenario_anexo}.

\subsection{O cliente do protocolo QoS-NSLP}
\label{cap4_cliente_protocolo NSLP}

Para iniciar uma sinalização e efetuar uma reserva, o cliente do protocolo
QoS NSLP, nsis-qos, é executado. Este cliente se comunica
com o ``daemon'' do nsis-qos, iniciado nos nós que terão passagem do fluxo.

Para iniciar uma sinalização, basta associar a chamada do cliente nsis-qos com
alguns parâmetros na linha de comando, conforme o modelo de mensagem a ser
utilizado. Dentre os
comandos, podemos citar:
\begin{itemize}
 \item -res: Envia uma mensagem de reserva para uma sessão;
 \item -rt: Envia uma reserva como flag T (Teardown Session) para remover uma
sessão;
 \item -q: Envia uma mensagem de prova, sem manter estado nos nós;
 \item -rir que faz a sinalização de reserva a partir do nó de destino.
\end{itemize}

Algumas considerações sobre o modelo devem ser aplicadas. O cliente do QoS-NSLP
assume que os dados de uma reserva já são conhecidos e passados a este. A
sinalização do caminho só ocorrerá após uma solicitação de fluxo, no nó entrante
e a reserva só ocorrerá nos nós QNE, onde estiver marcado para tal.

Utilizando o modo de análise do protocolo NSIS de Goettingen, foram feitas as
sinalizações e com base nas informações apresentadas pela depuração protocolo e
descrição no texto deste trabalho, foram feitos os devidos comentários.

%------------------------------------------------------------------------------%
\section{Cenário 1}
\label{cenario_ambiente1}
O modelo básico de sinalização do cliente NSIS QoS é a sinalização por fluxo
individual com reserva a partir do emissor do fluxo, ou seja, a sinalização de
reserva é feita no mesmo sentido do envio do fluxo. 

Este cenário, conforme figura abaixo, é composto dos nós QNI, QNE e QNR, sem
configuração de reserva de recursos, ou seja, as mensagens de reserva serão
geradas normalmente mas não existe função de gerenciamento de recursos nos nós.
Para isto, marcamos no arquivo nsis.conf a
opção qos.rmf com NullRMF: \verb|qos.rmf = NullRMF| . Com esta restrição,
mostraremos
somente a sinalização. O cenário montado é descrito em
\ref{fig:cap4_cenario_ambiente1}.

\begin{figure}[!htpb]
 \centering
 \includegraphics[scale=.6]{figs/cenario.png}
 \caption{Cenário}
 \label{fig:cap4_cenario_ambiente1}
\end{figure}

Esta sinalização também chamada de sinalização no sentido sentido
\textit{downstream}, conforme se observa nas informações do protocolo.

Utilizou-se de um ambiente com as três unidade da rede, um nó no QNR no core, e
nas pontas os nós QNI e QNR, cujas informações de endereço segue abaixo. O
s detalhes da configuração podem ser verificados no anexo \ref{cenario_anexo}.
\begin{itemize}
 \item QNI
IP: eth0=192.168.19.10/24;
NSIS com NullRMF;
 \item QNE
IP: eth0=192.168.19.11/24
IP: eth1=192.168.24.11/24
NSIS com NullRMF;
 \item QNR
IP: eth0=192.168.24.10/24;
NSIS como NullRMF;
\end{itemize}

Considerando o daemon nsis rodando em todos os nós, a partir do nó QNI, se
efetua sinalização com o comando:

 \verb|./nsis-qos 192.168.24.11 -res|

Onde aplicou-se o IP do nó de destino e a variável \textit{-res} para
sinalização de reserva. Veja que neste cenário não é efetuada reserva, e a
marcação de não efetuar reserva no nó QNE é respeitada.

Após a inicialização do comando, é gerado um fluxo de informações, coletadas do
modo depurador do protocolo, que podem ser melhores descritas a partir do nó
QNI.

\begin{enumerate}
\item O nó QNI envia um mensagem de sinalização para frente. E marca o tempo que
aguarda por resposta (RespTimer started   : 2s) e o tempo que ocorrerá a
mensagem de atualização de reserva.
\begin{verbatim}
NullRMF: client connected
We are End Node (QNI)
SID: ffffffff ffffffff ffffffff ffffffff
QoSFsm::idle__rx_rmf_msg()
QoSFsm::inst__rx_rmf_msg()

QNI: outgoing msg -->
+ SII_Handle        : 
+ srcAddr           : 192.168.19.11
+ destAddr          : 192.168.24.11
+ direction         : DOWNSTREAM
+ msg length        : 120 bytes
+ QoS Message Type  : RESERVE
+ T:R:B:A:P:S-Flag  : 0:0:0:0:0:0
RespTimer started   : 2s
RefrTimer started   : 30s
\end{verbatim}

\item O nó QNE verifica a mensagem, e encaminha para frente sem passar para a
camada de aplicação, pois não recebeu pedido de recurso. Aqui também
verificamos a marcação do tempo que ocorrerá a mensagem de atualização de
reserva e o tempo de armazenamento de estado, por se tratar de um no
\textit{statefull} (StateTimer started  : 100s).
\begin{verbatim}
We are Entity  (QNE)

QNE: --> incoming msg
+ SII_Handle        : 192.168.19.11
+ srcAddr           : 192.168.19.11
+ destAddr          : 192.168.24.11
+ direction         : DOWNSTREAM
+ msg length        : 120 bytes
+ QoS Message Type  : RESERVE
+ T:R:B:A:P:S-Flag  : 0:0:0:0:0:0

(...)

QNE: outgoing msg -->
+ SII_Handle        : 
+ srcAddr           : 192.168.19.11
+ destAddr          : 192.168.24.11
+ direction         : DOWNSTREAM
+ msg length        : 120 bytes
+ QoS Message Type  : RESERVE
+ T:R:B:A:P:S-Flag  : 0:0:0:0:0:0
RefrTimer started   : 30s
StateTimer started  : 100s
\end{verbatim}
\item O nó QNR então, recebe a mensagem e sinaliza a confirmação do recebimento.
\begin{verbatim}
! We are End Node (QNR) !

QNR: --> incoming msg
+ SII_Handle        : 192.168.24.10
+ srcAddr           : 192.168.19.11
+ destAddr          : 192.168.24.11
+ direction         : DOWNSTREAM
+ msg length        : 120 bytes
+ QoS Message Type  : RESERVE
+ T:R:B:A:P:S-Flag  : 0:0:0:0:0:0
\end{verbatim}

\end{enumerate}

Podemos de modo sequencial ver o conjunto de mensagens e a sequência na figura
\ref{fig:cap4_cenario_reserve1}

\begin{figure}[!htpb]
 \centering
 \includegraphics[scale=.4]{figs/cenario_reserve1.png}
 \caption{Sinalização de reserva}
 \label{fig:cap4_cenario_reserve1}
\end{figure}

Esta sinalização se mantém, até que o \textit{State Timer}, tempo que o estado
fica armazenado se encerre, ou até que o nó QNE receba uma mensagem com o flag T
marcado. Este, serve para identificar a remoção do estado (\textit{teardown}).

A partir do nó QNI, efetuou-se a solicitação de estouro do tempo de atualização
do estado, consequentemente a remoção deste, com a mensagem
 \verb|./nsis-qos 192.168.24.11 -rt|. Pode-se verificar o flag T marcado através
da mensagem:

\begin{verbatim}
 QNI: outgoing msg -->
+ SII_Handle        : 
+ srcAddr           : 192.168.19.11
+ destAddr          : 192.168.24.11
+ direction         : DOWNSTREAM
+ msg length        : 24 bytes
+ QoS Message Type  : RESERVE
+ T:R:B:A:P:S-Flag  : 1:0:0:0:0:0
\end{verbatim}

Outros meios de remoção do estado podem ocorrer com a queda de um dos pontos do
domínio. A mensagem tem um tempo de vida, que é armazenada, caso dentro deste
tempo não chegue atualização da reserva, esta é derrubada. 

%------------------------------------------------------------------------------%
\section{Cenário 2}
\label{cenario_ambiente2}
O modelo anterior, com a reserva no sentido downstream é um modelo básico de
sinalização, onde a sinalização é feita no sentido do fluxo. Contudo, o NSIS é
capaz de gerar a reserva de fluxo a partir do nó destino, para isto utilizamos o
comando -rir.

Neste caso, utilizou-se o mesmo ambiente do cenário anterior, conforme abaixo.
Caso queira visualizar detalhes da configuração, verifique o ítem
\ref{cenario_anexo}
\begin{itemize}
 \item QNR
IP: eth0=192.168.19.10/24;
NSIS com NullRMF;
 \item QNE
IP: eth0=192.168.19.11/24
IP: eth1=192.168.24.11/24
NSIS com NullRMF;
 \item QNI
IP: eth0=192.168.24.10/24;
NSIS como NullRMF;
\end{itemize}

Considerando o nsis rodando em todos os nós, a partir do nó QNR, efetuou-se a
solicitação de verificação de recursos, com uma mensagem QUERY e o nó QNI
efetuou o início de reserva de fluxo, com o uso do comando:

 \verb|./nsis-qos 192.168.24.11 -rir|

Onde \textit{-rir} para reserva a partir do receptor.

Repare que como os nós são tratado por QNI quem inicia a reserva e QNR, último
nó da reserva. Há neste cenário uma mudança na posição dos nós, isto poderemos
ver na sinalização do NSIS em cada host.

\begin{figure}[!htpb]
 \centering
 \includegraphics[scale=.4]{figs/cenario2.png}
 \caption{Sinalização de reserva com query}
 \label{fig:cap4_cenario_ambiente2}
\end{figure}

Com o comando -rir (Receiver Initiated Reservation) ativo o nsis gera
sinalização reserva pelo lado oposto ao que o fluxo é recebido. Para fazer
reserva a partir do receptor (Receiver Initiated Reservation), o QNR envia uma
mensagem QUERY, que pode conter uma especificação de fluxo. A mensagem QUERY
pode ser usado para coletar informações ao longo do caminho. Neste caso, será
feita uma consulta de estado no caminho, para isto a mensagem deve ter o Flag R
ativo e depois iniciado a reserva.

Analisando o tráfego a partir do nó QNE, que é o nó que fará a reserva, podemos
verificar o fluxo de mensagens:

\begin{verbatim}
We are End Node (QNR)

QNR: outgoing msg -->
+ SII_Handle        : 
+ srcAddr           : 192.168.19.11
+ destAddr          : 192.168.24.11
+ direction         : DOWNSTREAM
+ msg length        : 68 bytes
+ QoS Message Type  : QUERY
+ T:R:B:A:P:S-Flag  : 0:1:0:0:0:0
\end{verbatim}

O nó QNE recebe a sinalização de QUERY advinda do nó QNR (srcAddr=192.168.19.11)
para o nó QNI (destAddr=192.168.22.12). A função \verb|idle__rx_query()| marca o
recebimento de uma query pelo GIST e a passagem para a máquina de estado, que
estará esperando por uma resposta. Neste caso, o NSIS aciona a função
\verb|wr__rx_rmf_msg()| onde uma mensagem de reserva tenha sido acionada,
conforme a mensagem de saída do nó QNE.

\begin{verbatim}
We are Entity  (QNE)

QNE: --> incoming msg
+ SII_Handle        : 192.168.19.11
+ srcAddr           : 192.168.24.11
+ destAddr          : 192.168.19.11
+ direction         : UPSTREAM
+ msg length        : 68 bytes
+ QoS Message Type  : QUERY
+ T:R:B:A:P:S-Flag  : 0:1:0:0:0:0

triggerEvent        : ST_IDLE::EV_RX_QUERY

QoSFsm::idle__rx_query()
StateTimer started  : 30s

transition to       : ST_WR

QoSFsm::wr__rx_rmf_msg()
\end{verbatim}

Neste momento, o nó QNE recebe uma mensagem de RESERVE advinda do nó QNI,
contudo, repare na condição das informações do cabeçalho:

\begin{itemize}
\item SII\_Handle: 192.168.24.11: Repare abaixo que realmente a fonte (src) é
advinda do IP do nó QNI, contudo, o cabeçalho SII\_Handle vem marcado pelo
originador da sinalização. SII é na, tradução para o português, a informação que
identifica a fonte (Source Identification Information);
 \item srcAddr: 192.168.24.11: Originador da mensagem;
 \item destAddr: 192.168.19.11: Destino da mensagem;
\end{itemize}

Com isto, a mensagem de reserva é enviada, contudo, para o nó QNE, que efetuará
a reserva, a marcação será de maneira correta, no sentido do fluxo.

\begin{verbatim}
QNE: --> incoming msg
+ SII_Handle        : 192.168.24.11
+ srcAddr           : 192.168.24.11
+ destAddr          : 192.168.19.11
+ direction         : DOWNSTREAM
+ msg length        : 80 bytes
+ QoS Message Type  : RESERVE
+ T:R:B:A:P:S-Flag  : 0:0:0:0:0:0
\end{verbatim}

O fluxo de mensagens pode ser melhor detalhado a seguir:
\begin{figure}[!htpb]
 \centering
 \includegraphics[scale=.4]{figs/cenario_reserve2.png}
 \caption{Fluxo de Sinalização de reserva com query}
 \label{fig:cap4_cenario_reserve_2}
\end{figure}

%------------------------------------------------------------------------------%
\section{Cenário 3}
\label{cenario_ambiente3}
Nos cenários anteriores, somente mostramos a sinalização, sem nenhuma alocação
de recurso para o fluxo. Isto porque o nó QNE estava marcado para não efetuar a
reserva. Contudo, o nsis permite junto a sinalização o envio da entidade QSPEC
com a especificação de fluxo que se destina para tal e esta é entendida pelo
gerenciador de recurso. Faremos então um modelo sinalização, do cliente NSIS
QoS, por fluxo individual com reserva a partir do emissor do fluxo, ou seja, a
sinalização é feita no mesmo sentido do envio do fluxo.

Este cenário, conforme figura abaixo, é composto dos nós QNI, QNE e QNR, com
configuração de reserva de recursos para o nó central QNE. Para isto, alteramos
no nsis.conf o parâmetro qos.rmf para SimpleRMF (qos.rmf = SimpleRMF), conforme
cenário:

\begin{figure}[!htpb]
 \centering
 \includegraphics[scale=.6]{figs/cenario3.png}
 \caption{Cenário com reserva de recurso}
 \label{fig:cap_cenario}
\end{figure}

A reserva é feita utilizando ferramentas do pŕoprio linux, como o IPTABLES e o
TC. O é iptables uma ferramenta de filtro de redes baseado em regras pré
determinadas. O TC (traffic control) é uma ferramenta de controle de tráfego e
pode ser utilizada para gerenciamento de QoS em redes.

O TC implementa o QDISC como algoritmo de classificação de tráfego na saída do
fluxo. o QDISC (Queueing Discipline) é capaz de gerenciar o fluxo de uma
interface, seja na entrada ou na saída do fluxo. O qdisc tem uma raiz
\textit{root} que é associada a uma interface.

No qdisc adicionam-se classes onde são implementadas as políticas de tratamento
do fluxo. Dentro de uma classe podem haver outras classes além de outro qdisc,
com outra disciplina de fluxo. Portanto, uma classe pode ter um qdisc como pai
\textit{parent} ou uma outra classe. O qdisc precisa de um classificador para
determinar qual a classe que precisa enviar um pacote.isto é feito utilizando o
\textit{filter}.

Para este cenários, utilizou-se de um ambiente semelhante aos anteriores, com
somente um nó QNE no core e este efetua a reserva, conforme abaixo. Caso queira
visualizar detalhes da configuração, verifique o ítem \ref{cenario_anexo}.
\begin{itemize}
 \item QNI
IP: eth0=192.168.19.10/24;
NSIS como NullRMF;
Software iperf como cliente para fluxo priorizado;
 \item QNE
IP: eth0=192.168.19.11/24
IP: eth1=192.168.24.11/24
NSIS como SimpleRMF, fazendo reserva;
 \item QNR
IP: eth0=192.168.24.10/24;
NSIS como NullRMF;
Software iperf como servidor do fluxo priorizado;
\end{itemize}

Durante a inicialização do NSIS no nó QNE com a marcação para SimpleRMF,
verifica-se o tc rodando, inicialmente apaga as classes que poderiam ter sido
criadas e em seguida monta a estrutura de priorização:
\begin{verbatim}
(TC) Running "tc qdisc delete dev eth1 root handle 1:"
(IpTables) Running "iptables -t mangle -F PREROUTING"
(IpTables) Running "ip6tables -t mangle -F PREROUTING"
(TC) Running "tc qdisc add dev eth1 root handle 1: htb default 2"
(TC) Running "tc class add dev eth1 parent 1: classid 1:1 htb rate 100kbit ceil
100kbit burst 100kbit"
(TC) Running "tc class add dev eth1 parent 1:1 classid 1:2 htb rate 100kbit
burst 100kbit ceil 0 mpu 0"
(TC) Running "tc qdisc add dev eth1 parent 1:2 handle 2: sfq perturb 10"
\end{verbatim}

A estrutura criada pode ser visualizada conforme ilustração:
\begin{figure}[!htpb]
 \centering
 \includegraphics[scale=.4]{figs/tc_start_nsis.png}
 \caption{Criação da estrutura de controle de tráfego}
 \label{fig:cap4_tc_start_nsis}
\end{figure}

Verifique que é aplicado uma classe com taxa \textit{rate} de 100kbit limitando
o fluxo não priorizado, o que pode ser visto com o iperf:

\begin{verbatim}
(none):~# iperf -s -i 0
WARNING: interval too small, increasing from 0.00 to 0.5 seconds.
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 85.3 KByte (default)
------------------------------------------------------------
[  4] local 192.168.24.12 port 5001 connected with 192.168.19.12 port 35855
[  4]  0.0- 0.5 sec  9.90 KBytes    162 Kbits/sec
[  4]  0.5- 1.0 sec  4.24 KBytes  69.5 Kbits/sec
[  4]  1.0- 1.5 sec  5.66 KBytes  92.7 Kbits/sec
[  4]  1.5- 2.0 sec  4.24 KBytes  69.5 Kbits/sec
[  4]  2.0- 2.5 sec  7.07 KBytes    116 Kbits/sec
[  4]  2.5- 3.0 sec  5.66 KBytes  92.7 Kbits/sec
[  4]  3.0- 3.5 sec  5.66 KBytes  92.7 Kbits/sec
[  4]  3.5- 4.0 sec  5.66 KBytes  92.7 Kbits/sec
[  4]  4.0- 4.5 sec  5.66 KBytes  92.7 Kbits/sec
[  4]  4.5- 5.0 sec  5.66 KBytes  92.7 Kbits/sec
[  4]  5.0- 5.5 sec  5.66 KBytes  92.7 Kbits/sec
[  4]  5.5- 6.0 sec  5.66 KBytes  92.7 Kbits/sec
\end{verbatim}

Considerando o nsis rodando em todos os nós, a partir do nó QNI, se efetua
solicitação de reserva de fluxo com o comando:

 \verb|./nsis-qos 192.168.24.11 -res -bw 50 -p 6 -dpt 9876|

Onde \textit{-res} de reserva, \textit{-bw} para especificar a quantidade de
banda desejada em bytes por segundo, \textit{-p 6} para utilizar protocolo TCP e
\textit{-dpt 9876} para especificar uma porta de destino para a reserva.

Neste momento é gerado um fluxo de informações, coletadas do modo debug do
protocolo, que podem ser melhores descritas a partir do nó QNI.

\begin{enumerate}
\item O Nó QNI envia um mensagem de reserva;
\item Após recebe uma mensagem NOTIFY confirmando que existe recurso: ``RR
supported.``
\item A partir da confirmação o nó QNI envia uma mensagem de resposta RESPONSE
para informar o envio do fluxo.
\end{enumerate}

Podemos de modo sequencial ver o conjunto de mensagens e a sequência na figura
\ref{fig:cap4_cenario_reserve3}

\begin{itemize}
 \item QNI sinaliza para QNR;
 \item QNE intermedia e verifica informações;
 \item QNE aloca recursos;
\begin{verbatim}
Reserving ...
(TC) Running "tc class add dev eth1 parent 1:1 classid 1:6 htb rate 500bps burst
500 ceil 500bps mpu 64"
HTB: quantum of class 10006 is small. Consider r2q change.
(TC) Running "tc qdisc add dev eth1 parent 1:6 handle 6: sfq perturb 10"
(TC) Running "tc filter add dev eth1 protocol ip parent 1:0 prio 1 u32 match ip
src 192.168.19.11/32 match ip dst 192.168.24.11/32 match ip protocol 6 0xff
match ip dport 9876 0xffff  flowid 1:6"
\end{verbatim}
 \item As atualizações de máquina de estado são encaminhadas entre os nós
+++ QSPEC object    : QoS Available
+++ Object type     : Tmod1, length:4
+++ QSPEC object    : Minimum QoS
\item QNR responde a sinalização
\item QNE respode a QNI e reserva recursos.
\end{itemize}

\begin{figure}[!htpb]
 \centering
 \includegraphics[scale=.4]{figs/cenario_reserve1.png}
 \caption{Sinalização de reserva}
 \label{fig:cap4_cenario_reserve3}
\end{figure}

Após a reserva de recursos, o estado da garantia de recursos se mantém por
sinalização de estado, soft-state, gerada de tempos em tempos. Esta mensagem tem
o intuito apenas de manter o estado e carrega informações de fonte e destino, ID
da reserva e tipo de mensagem. O evento é gerado pelo nó QNI, que ao chegar ao
nó QNE chama a função \verb|inst__rx_reserve()|, que compara o identificador da
reserva com os atuais, se o valor for o mesmo que o armazenado, a reserva é
atualizada. Um modelo pode ser visto abaixo:

\begin{verbatim}
----------------------------------------
QoSFsm: refresh_timeout()

triggerEvent        : ST_INST::EV_TIMEOUT_REFRESH

QoSFsm::inst__timeout_refresh()

QNE: outgoing msg -->
+ SII_Handle        : 
+ srcAddr           : 192.168.19.11
+ destAddr          : 192.168.24.11
+ direction         : DOWNSTREAM
+ msg length        : 16 bytes
+ QoS Message Type  : RESERVE
+ Object Type       : RSN
++ RSN              : 1
+ T:R:B:A:P:S-Flag  : 0:0:0:0:0:0
RefrTimer restarted : 30s

transition to       : ST_INST

SID: ffffffff ffffffff ffffffff ffffffff
fsm                 : 0x80f4c28

QNE: --> incoming msg
+ SII_Handle        : 192.168.19.11
+ srcAddr           : 192.168.19.11
+ destAddr          : 192.168.24.11
+ direction         : DOWNSTREAM
+ msg length        : 16 bytes
+ QoS Message Type  : RESERVE
+ Object Type       : RSN
++ RSN              : 1
+ T:R:B:A:P:S-Flag  : 0:0:0:0:0:0

triggerEvent        : ST_INST::EV_RX_RESERVE

QoSFsm::inst__rx_reserve()
StateTimer restarted: 100s

transition to       : ST_INST

\end{verbatim}

Para se remover uma reserva, basta utilizar o parâmetro -t, de derrubar (do
inglês teardown). Este modelo ativa o flag T que associa um tempo para a
reserva, se associado sem tempo determinado, remove a reserva. O procedimento de
remoção de reserva também pode ser feito manualmente, como no exemplo:

\verb|./nsis-qos 192.168.24.11 -rt -bw 50 -p 6 -dpt 9876|

Para o caso desta sinalização utilizou-se os mesmo parâmetros da reserva,
contudo, o flag T foi enviado com o parâmetro \textit{-rt}.

Outros meios são a queda de um dos pontos do domínio. A reserva tem um tempo de
vida, que é armazenada, caso dentro deste tempo não chegue atualização da
reserva, esta é derrubada. 

\begin{verbatim}
SID: ffffffff ffffffff ffffffff ffffffff
fsm                 : 0x80f4c28

QNE: --> incoming msg
+ SII_Handle        : 192.168.19.11
+ srcAddr           : 192.168.21.11
+ destAddr          : 192.168.24.11
+ direction         : DOWNSTREAM
+ msg length        : 24 bytes
+ QoS Message Type  : RESERVE
+ T:R:B:A:P:S-Flag  : 1:0:0:0:0:0

triggerEvent        : ST_INST::EV_RX_RESERVE

QoSFsm::inst__rx_reserve()
StateTimer started  : 30s

transition to       : ST_WR
\end{verbatim}

Novamente a mensagem é recebida, é feita a chamada função
\verb|inst__rx_reserve()|, da máquina de estado, verifica o marcador T-FLAG
setado (campo T:R:B:A:P:S-Flag:), e libera a reserva.

\begin{verbatim}
Refresh Timer stoped
Releasing reservation ...
(TC) Running "tc filter delete dev eth1 protocol ip parent 1:0 prio 1 u32 match
ip src 192.168.19.11/32 match ip dst 192.168.24.11/32 match ip protocol 6 0xff
match ip dport 9876 0xffff  flowid 1:6"
(TC) Running "tc class delete dev eth1 parent 1:1 classid 1:6"
QoSFsm::wr__rx_rmf_msg()
\end{verbatim}

%------------------------------------------------------------------------------%
\section{Cenário 4}
\label{cenario_ambiente4}

No cenário anterior pode-se verificar o mecanismo de reserva de recurso RMF
atuando. Foi efetuado sinalização com reserva e o mecanismo de gerência de
recursos efetuou esta reserva, contudo foi feita apenas uma reserva para um
fluxo individual.

Contudo, o RMF deve efetuar a gerência de recurso, para as requisições que
entram e solicitam alocação. Para identificarmos reduziremos o tamanho de
alocação de banda para 100kbit e efetuaremos várias reservas, em seguida
observaremos o comportamento.

Para este cenários, utilizou-se de um ambiente semelhante aos anteriores, com
somente um nó QNE no core e este efetua a reserva, contudo, utilizaremos dois
nós adjacentes além dos utilizados, pra fluxo não priorizado conforme abaixo.
Caso queira visualizar detalhes da configuração, verifique o ítem
\ref{cenario_anexo}.

\begin{figure}[!htpb]
 \centering
 \includegraphics[scale=.6]{figs/cenario4.png}
 \caption{Cenário com reserva de recurso}
 \label{fig:cap4_cenario4}
\end{figure}

Cuja configuração básica:

\begin{itemize}
 \item QNI
IP: eth0=192.168.19.10/24;
NSIS como NullRMF;
Software iperf como cliente para fluxo priorizado;
 \item QNI
IP: eth0=192.168.19.12/24;
NSIS como NullRMF;
Software iperf como cliente para fluxo não priorizado;
 \item QNE
IP: eth0=192.168.19.11/24
IP: eth1=192.168.24.11/24
NSIS como SimpleRMF, fazendo reserva;
 \item QNR
IP: eth0=192.168.24.10/24;
NSIS como NullRMF;
Software iperf como servidor do fluxo priorizado;
 \item QNR
IP: eth0=192.168.24.12/24;
NSIS como NullRMF;
Software iperf como servidor do fluxo não priorizado;
\end{itemize}

Na inicialização do nsis, é aplicado uma classe com taxa \textit{rate} de
100kbit limitando o fluxo não priorizado, o que pode ser visto com o iperf:

\begin{verbatim}
(none):~# iperf -s -i 0
WARNING: interval too small, increasing from 0.00 to 0.5 seconds.
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 85.3 KByte (default)
------------------------------------------------------------
[  4] local 192.168.24.12 port 5001 connected with 192.168.19.12 port 35855
[  4]  0.0- 0.5 sec  9.90 KBytes    162 Kbits/sec
[  4]  0.5- 1.0 sec  4.24 KBytes  69.5 Kbits/sec
[  4]  1.0- 1.5 sec  5.66 KBytes  92.7 Kbits/sec
[  4]  1.5- 2.0 sec  4.24 KBytes  69.5 Kbits/sec
[  4]  2.0- 2.5 sec  7.07 KBytes    116 Kbits/sec
[  4]  2.5- 3.0 sec  5.66 KBytes  92.7 Kbits/sec
[  4]  3.0- 3.5 sec  5.66 KBytes  92.7 Kbits/sec
[  4]  3.5- 4.0 sec  5.66 KBytes  92.7 Kbits/sec
[  4]  4.0- 4.5 sec  5.66 KBytes  92.7 Kbits/sec
[  4]  4.5- 5.0 sec  5.66 KBytes  92.7 Kbits/sec
[  4]  5.0- 5.5 sec  5.66 KBytes  92.7 Kbits/sec
[  4]  5.5- 6.0 sec  5.66 KBytes  92.7 Kbits/sec
\end{verbatim}

A cada reserva, será criada uma nova disciplina, que tratará o fluxo informado.
O RMF tratará o fluxo de acordo com as informações passadas pela sinalização e
fará os cálculos necessários para a agregação desta reserva.

Em nosso cenário solicitaremos 4 reservas de fluxo, de 50Kbps, 40kbps, 10kpbs e
10kbps respectivamente. Contudo, deve-se atentar para um detalhe, nosso link foi
limitado a 100kbps, ou seja, a última reserva, de 10kps não poderá ser feita, a
menos que uma das anteriores seja retirada, devido a saturação do link.

Efetua-se então as reservas a partir do QNI:
\begin{itemize}
 \item Para 50kbps
\verb|./nsis-qos 192.168.24.11 -res -bw 50000 -p 6 -sid 76 -dpt 9876|
 \subitem E verifica-se a reserva no nó QNE:
\begin{verbatim}
 Reserving ...
(TC) Running "tc class add dev eth1 parent 1:1 classid 1:6 htb rate 48kbps burst
50000 ceil 48kbps mpu 64"
(TC) Running "tc qdisc add dev eth1 parent 1:6 handle 6: sfq perturb 10"
(TC) Running "tc filter add dev eth1 protocol ip parent 1:0 prio 1 u32 match ip
src 192.168.19.11/32 match ip dst 192.168.24.11/32 match ip protocol 6 0xff
match ip dport 9876 0xffff  flowid 1:6"
\end{verbatim}

 \item Em seguida, efetuamos a reserva de Para 40kbps
\verb|./nsis-qos 192.168.24.11 -res -bw 40000 -p 6 -sid 77 -dpt 9877|
 \subitem E verifica-se a reserva no nó QNE:
\begin{verbatim}
Reserving ...
(TC) Running "tc class add dev eth1 parent 1:1 classid 1:7 htb rate 39kbps burst
40000 ceil 39kbps mpu 64"
(TC) Running "tc qdisc add dev eth1 parent 1:7 handle 7: sfq perturb 10"
(TC) Running "tc filter add dev eth1 protocol ip parent 1:0 prio 1 u32 match ip
src 192.168.19.11/32 match ip dst 192.168.24.11/32 match ip protocol 6 0xff
match ip dport 9877 0xffff  flowid 1:7"
\end{verbatim}

 \item Em seguida, efetuamos a reserva de Para 10kbps
\verb|./nsis-qos 192.168.24.11 -res -bw 10000 -p 6 -sid 78 -dpt 9878|
 \subitem E verifica-se a reserva no nó QNE:
\begin{verbatim}
Reserving ...
(TC) Running "tc class add dev eth1 parent 1:1 classid 1:8 htb rate 10000bps
burst 10000 ceil 10000bps mpu 64"
(TC) Running "tc qdisc add dev eth1 parent 1:8 handle 8: sfq perturb 10"
(TC) Running "tc filter add dev eth1 protocol ip parent 1:0 prio 1 u32 match ip
src 192.168.19.11/32 match ip dst 192.168.24.11/32 match ip protocol 6 0xff
match ip dport 9877 0xffff  flowid 1:8"
\end{verbatim}

\item No entanto, conforme esperado a última reserva não foi efetuada, pois não
havia banda suficiente para alocação.
\verb|./nsis-qos 192.168.24.11 -res -bw 10000 -p 6 -sid 79 -dpt 9879|
\end{itemize}

\begin{figure}[!htpb]
 \centering
 \includegraphics[scale=.6]{figs/tc_reserv_nsis.png}
 \caption{Classes de fluxo do controle de tráfego}
 \label{fig:cap4_tc_reserv_nsis}
\end{figure}

Com as alocações de banda efetuadas, cada fluxo priorizado tem a admissão de
banda garantida sobre fluxos não priorizados. Isto pode ser visto utilizando o
iperf, para isto foi efetuada a reserva de 50kbps e a de 40 kbps, restando
10kbps para o fluxo não priorizado. Em paralelo, jogamos colocamos tráfego na
rede, conforme a reserva e verificamos a garantia de banda.

\begin{itemize}
 \item Taxa de tráfego para o fluxo priorizado:
\begin{verbatim}
WARNING: interval too small, increasing from 0.00 to 0.5 seconds.

------------------------------------------------------------
Server listening on TCP port 9877
TCP window size: 85.3 KByte (default)
------------------------------------------------------------
[  4] local 192.168.24.11 port 9877 connected with 192.168.19.11 port 40751
[  4]  0.0- 0.5 sec  4.24 KBytes  69.5 Kbits/sec
[  4]  0.5- 1.0 sec  2.83 KBytes  46.3 Kbits/sec
[  4]  1.0- 1.5 sec  2.83 KBytes  46.3 Kbits/sec
[  4]  1.5- 2.0 sec  1.41 KBytes  23.2 Kbits/sec
[  4]  2.0- 2.5 sec  1.41 KBytes  23.2 Kbits/sec
[  4]  2.5- 3.0 sec  2.83 KBytes  46.3 Kbits/sec
 \end{verbatim}

 \item Taxa de tráfego para o fluxo não priorizado:
\begin{verbatim}
 (none):/NSIS/nsis-0.6.0/bin# iperf -s -i 0
WARNING: interval too small, increasing from 0.00 to 0.5 seconds.
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 85.3 KByte (default)
------------------------------------------------------------
[  4] local 192.168.24.12 port 5001 connected with 192.168.19.12 port 40718
[  4]  0.0- 0.5 sec  4.24 KBytes  46.3 Kbits/sec
[  4]  0.5- 1.0 sec  4.24 KBytes  0.00 Kbits/sec
[  4]  1.0- 1.5 sec  2.83 KBytes  0.00 Kbits/sec
[  4]  1.5- 2.0 sec  2.83 KBytes  0.00 Kbits/sec
[  4]  2.0- 2.5 sec  1.41 KBytes  23.2 Kbits/sec
[  4]  2.5- 3.0 sec  1.41 KBytes  23.2 Kbits/sec
[  4]  3.0- 3.5 sec  2.83 KBytes  0.00 Kbits/sec
[  4]  3.5- 4.0 sec  1.41 KBytes  0.00 Kbits/sec
\end{verbatim}
\end{itemize}

%------------------------------------------------------------------------------%
\section{Cenário 5}
\label{cenario_ambiente5}

Neste cenário, observamos um dos modelos do NSIS que o diferencia de modelos de
sinalização , como o RSVP, por exemplo. A capacidade de reler a tabela de
roteamento e refazer a reserva em caso de mudança de rota. Na mensagem de
atualização de estado, verificamos que o NSIS analisa se a reserva já existia, e
caso nao exista, esta é efetuada.

Como o NSIS é um protocolo em desenvolvimento, este modelo ainda não foi
implementado em sua totalidade, contudo, foram efetuadas as devidas análises.

No cenário utilizado deu-se preferência para que cada nó do cenário efetua-se
uma tarefa, sendo que as bordas fazem e recebem a sinalização, o nó central faz
a reserva deixando outros dois nós exclusivos ao roteamento.

\begin{figure}[!htpb]
 \centering
 \includegraphics[scale=.4]{figs/cenario5.png}
 \caption{Sinalização com mudanca de rota}
 \label{fig:cap4_cenario_change_route}
\end{figure}

No cenário montado o nsis foi inicializado em todos os nós, e uma reserva foi
feita de uma ponta a outra. No nó que funciona como roteador a rota estava fixa,
para o fluxo ser transmitido pela rede 192.168.20.0/24 e 192.168.22.0/24. Para
efetuar a troca de rota, foram criados dois arquivos, que quando executados
apagavam a rota de um caminho e redirecionavam para outro, conforme o arquivo:

\begin{itemize}
 \item Roteador da ponta QNI
route add default gw 192.168.20.11 eth0
route del default gw 192.168.21.11 eth1
route del -net 192.168.22.0 netmask 255.255.255.0 gw 192.168.20.11 eth0
route del -net 192.168.24.0 netmask 255.255.255.0 gw 192.168.21.11 eth1
route del -net 192.168.23.0 netmask 255.255.255.0 gw 192.168.21.11 eth1

 \item Roteador da ponta QNR
route add default gw 192.168.22.11 eth1
route del default gw 192.168.23.11 eth0
route del -net 192.168.20.0 netmask 255.255.255.0 gw 192.168.22.11 eth1
route del -net 192.168.19.0 netmask 255.255.255.0 gw 192.168.23.11 eth0
route del -net 192.168.21.0 netmask 255.255.255.0 gw 192.168.23.11 eth0
\end{itemize}

Bem como para alternarmos a rota pela rede 192.168.21.0/24 e 192.168.23.0/24, o
arquivo abaixo com a rotas era executado:

\begin{itemize}
 \item Roteador da ponta QNI
route add default gw 192.168.21.11 eth1
route del default gw 192.168.20.11 eth0
route del -net 192.168.24.0 netmask 255.255.255.0 gw 192.168.21.11 eth1
route del -net 192.168.23.0 netmask 255.255.255.0 gw 192.168.21.11 eth1
route del -net 192.168.22.0 netmask 255.255.255.0 gw 192.168.20.11 eth0

 \item Roteador da ponta QNR
route del default gw 192.168.22.11 eth1
route add default gw 192.168.23.11 eth0
route del -net 192.168.19.0 netmask 255.255.255.0 gw 192.168.23.11 eth0
route del -net 192.168.20.0 netmask 255.255.255.0 gw 192.168.22.11 eth1
route del -net 192.168.21.0 netmask 255.255.255.0 gw 192.168.23.11 eth0
\end{itemize}

Durante a inicialização do daemon nsis, a configuração de roteamento é carregada
pelo nsis. Tanto se explícita no arquivo, nsis.conf como se lendo a tabela de
roteamento. Durante o teste, foi verificado que ainda não foi implementado
entidade que verifique a mudança de rota e atualize o nsis para a nova tabela de
roteamento.

A importância do protocolo de sinalização conhecer a tabela de roteamento se dá
em conhecer o caminho e o destino do fluxo além da capacidade de detectar a
mudança por conparação de rota.

Neste mesmo cenário, com a mudança de rota, a sinalização perde o ponto onde
havia a reserva ja feita, e pode-se observar a entidade soft-state atuando.

(terminar o soft-state)
% --------------------------------------- %

\chapter{Montagem de Máquinas Virtuais}
\label{Montar_vm}

Diante da facilidade e sendo uma boa solução, o ambiente de testes foi montado
fazendo uso de máquinas virtuais. A UML (User Mode Linux) é nativa no linux e
apresenta alto desempenho.

O uso das máquinas virtuais UML é muito fácil, simplesmente é necessário um
kernel compilado para este tipo especifico de arquitetura e um filesystem. Neste
trabalho, utilizamos tanto o host como a máquina virtual baseado na distribuição
Debian.

\subsubsection{Criando o Kernel}
\label{Montar_vm_kernel}

Para montar a máquina virtual é preciso um kernel compilado para a arquitetura
UML. Para este ambiente foi utilizado a versão 2.6.25.6 do kernel. A criação de
um kernel linux para uml é um procedimento relativamente simples, conforme
descrito com os passos abaixo:

\begin{verbatim}
$ wget http://kernel.org/pub/linux/kernel/v2.6/linux-2.6.25.6.tar.bz2
$ tar jxvf linux-2.6.25.6.tar.bz2
$ cd linux-2.6.25.6
\end{verbatim}

Como o ambiente de testes será utilizado máquinas virtuais devemos compilar o
kernel para essa arquitetura:

\verb|$ export ARCH=um|

Configurando kernel:

\verb|$ make defconfig|
\verb|$ make menuconfig|

É interessante habilitar a opção HOSTFS para as máquinas virtuais terem acesso
ao filesystem do host e as opções que estão em desuso do NETLINK. Para
configurar o kernel com suporte as opções deste trabalho, selecione no kernel as
opções de FIREWALL e as tabelas (NAT, MANGLE, FILTER), NET, NETLINK, e opções de
QoS. Estas opções devem ser setadas, no arquivo .config:

Após configurado o kernel deve ser compilado, os seus módulos serão instalados
no diretório uml-modules para depois serem copiados para o filesystem da máquina
virtual. O filesystem pode ser obtido no site
\textit{http://uml.nagafix.co.uk/}, que contém também também alguns kernels do
linux pré-compilados.

\begin{verbatim}
$ make
$ strip linux
$ make modules_install INSTALL_MOD_PATH=uml-modules
$ unset arch
\end{verbatim}

Como se faz uso de máquinas virtuais é necessário copiar os módulos para o
filesystem que será utilizado. Para isso:

\begin{verbatim}
# mkdir loop
# mount -o loop <seu_fs> loop
# cp -rf linux-2.6.25.6/uml-modules/lib/modules/* loop/lib/modules
\end{verbatim}

\subsubsection{Interface comunicação VM/Host}
\label{Montar_vm_Interface_vm-host}
Para criar algumas funções de comunicação que podem ser úteis durante o uso da
máquina virtual, aconselha-se a instalação dos seguintes pacotes:

\verb|#apt-get install uml-utilities openvpn openssl|

Existem dois modos para criar interfaces de rede para a máquina virtual, através
de interface virtual do host com o tunctl ou através do uml\_switch.

\verb|# tunctl -u \textit{seu_usuario}|

O comando acima cria um interface virtual, por exemplo, tap0. Se invocado
novamente criar a tap1 e sucessivamente. Esta interface permite que a máquina
virtual possa acessar a internet, o que facilita a instalação de pacotes dentro
da mesma.

Configure a interface normalmente

\verb|# ifconfig tap0 192.168.20.1 up|

Para apagar a interface, utilize a opção -d:

\verb|# tunctl -d tap0|

Ative o roteamento de pacotes na máquina host

\verb|# echo 1 > /proc/sys/net/ipv4/ip_forward|

Ha outro meio de criar uma interface de rede para conectar as máquinas virtuais,
que cria um switch, utilizando a uml\_switch. Este modo foi o utilizado neste
trabalho para a montagem de cenários, para isto crie um switch com o comando:


\verb|$ uml_switch -unix /tmp/net100.ctl|

Onde net100.ctl é o nome do switch que será referenciado na inicialização da
UML.


\subsubsection{Utilizando a máquina Virtual}
\label{Montar_vm_utilizar_vm}
Após criado o Kernel e o Filesystem com os módulos do kernel compilado, pode-se
invocar a máquina virtual, certificando-se de apontar os arquivos conforme
diretório.

Para chamar a máquina virtual, altere a interface de comunicação conforme
abaixo:

\verb*|$ xterm -title Debian1 -e ./linux ubda=Debian-4.0-x86-root_fs|
\verb*|eth0=daemon,,,/tmp/net100.ctl|

Ou para compartilhar através da interface tap0:

\verb|$ xterm -title Debian1 -e ./linux ubd0=Debian-4.0-x86-root_fs|
\verb*|eth0=tuntap,tap0|

Ou Ainda...

\verb|$ xterm -title Debian1 -e ./linux-ro|
\verb*|ubd0=./cow-host1,./Debian-4.0-x86-root_fs eth0=tuntap,tap0|

Neste últmo caso, cria-se um filesystem de uma máquina virtual, como
"cow-host1", que poderá ser invocado conforme o primeiro comando. Neste modo, as
configurações feitas e salvas no ``cow-host1'' poderão ser utilizadas na próxima
inicialização.

Onde:
\begin{enumerate}
 \item xterm: Programa para abrir a máquina virtual em janela do Ambiente
Gráfico, com os seguintes parâmetros:

\begin{itemize}
 \item -title: Passa o nome para a janela do xterm
 \item -e: Passa comando para ser executado dentro da janela do xterm. Aqui
chamaremos a máquina virtual.
\end{itemize}

 \item ./linux: Passe o caminho do kernel da Máquina Virtual.
 \item ubd0=: Passe o caminho do Filesystem da Máquina Virtual.
 \item eth0=: A interface de rede que a máquina virtual irá comunicar, exemplo:
tuntap,tap0
\end{enumerate}

\subsubsection{Montando o diretório do Host na Máquina Virtual}
\label{Montar_vm_montar_host-vm}
Na máquina host, crie uma pasta com o comando:

\verb|# mkdir host|

Com a máquina virtual funcionado, trabalhe como um sistema operacional igual.

Monte o diretório do host na máquina virtual:

\verb|# mount none /host(pasta VM) -t hostfs -o /home/rodrigo(pasta host)|

Você também pode montar a unidade de mídia removível, conforme segue:

\verb|# mount none /cdrom -t hostfs -o /cdrom/|

Acese o diretório correspondente ao cdrom.

\verb|# mount none /cdrom/ -t hostfs udf,iso9660 -o /cdrom/|